package com.zero2oneit.mall.search.service.impl;

import com.zero2oneit.mall.common.utils.EsIndexConstant;
import com.zero2oneit.mall.common.utils.R;
import com.zero2oneit.mall.common.utils.StringUtils;
import com.zero2oneit.mall.common.utils.bootstrap.BoostrapDataGrid;
import com.zero2oneit.mall.search.mapper.EsGoodProMapper;
import com.zero2oneit.mall.search.qo.IndexSearchQo;
import com.zero2oneit.mall.search.qo.ShopTypeGoodQo;
import com.zero2oneit.mall.search.service.GoodProEsService;
import com.zero2oneit.mall.search.vo.BusinessGoods;
import com.zero2oneit.mall.search.vo.YzProSkuVo;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import static org.elasticsearch.index.query.QueryBuilders.*;

/**
 * @author Lee
 * @date 2020/7/30 -15:30
 */
@Service
public class GoodProEsServiceImpl implements GoodProEsService {

    @Autowired
    private EsGoodProMapper esMapper;

    public List productSkuByProId(String id) {
        return esMapper.esSelectList(EsIndexConstant.COMMUNITY_SKU_INDEX, termQuery("productId", id), Map.class,null);
    }

    @Override
    public Map skuListStock(List<String> list) {
        return esMapper.skuListStock(list,EsIndexConstant.COMMUNITY_SKU_INDEX,new String[] {"productStock","fnPrice"});
    }

    @Override
    public Map getByIndexAndId(String index,String id) {
        boolean exists = esMapper.exists(index,id);
        if (exists){
            GetResponse response = esMapper.getById(index, id);
            return response.getSource();
        }
        return null;
    }

    @Override
    public R keywordSearch(Map<String,String> map) {
        if (!StringUtils.isEmpty(map.get("keyword"))){
            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                    .must(boolQuery().should(matchPhraseQuery("productName",map.get("keyword")))
                            .should(matchPhraseQuery("productTypeName",map.get("keyword")))
                            .should(matchPhraseQuery("productDesc",map.get("keyword"))));
            if (!StringUtils.isEmpty(map.get("plateIds"))){
                queryBuilder.must(boolQuery().should(wildcardQuery("plateIds", map.get("plateIds")+"_*"))
                        .should(wildcardQuery("plateIds", "*_" + map.get("plateIds") + "_*"))
                        .should(wildcardQuery("plateIds", "*_" + map.get("plateIds"))));
            }
            return R.ok(esMapper.esSelectCommon(EsIndexConstant.GOOD_INDEX,queryBuilder,Map.class,
                    (Integer.parseInt(map.get("currentPage"))-1)*Integer.parseInt(map.get("size")),
                    Integer.parseInt(map.get("size")),map.get("sort"),null));
        }
        return R.fail("请输入关键字");
    }

    @Override
    public BoostrapDataGrid myProSearch(Map<String, String> map, String index) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().
                must(termQuery("businessId",map.get("businessId"))).must(termQuery("appType",map.get("appType")));
        if (!StringUtils.isEmpty(map.get("keyword"))){
               queryBuilder.must(matchQuery("productName",map.get("keyword")));
        }
        return esMapper.esSelectCommon(index,queryBuilder,Map.class,
                (Integer.parseInt(map.get("currentPage"))-1)*Integer.parseInt(map.get("size")),
                Integer.parseInt(map.get("size")),map.get("sort"),null);
    }

    @Override
    public BoostrapDataGrid yzProSearch(Map<String, String> map) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(matchPhraseQuery("productName",map.get("keyword")));
        BoostrapDataGrid boostrapDataGrid = esMapper.esSelectCommon(EsIndexConstant.COMMUNITY_GOOD_INDEX, queryBuilder, Map.class,
                null, null, null,1);
        List<Map> rows = (List<Map>) boostrapDataGrid.getRows();
        if (rows.size()!=0){
            Map skuMap = esMapper.yzSkuList(rows, EsIndexConstant.COMMUNITY_SKU_INDEX);
            List<YzProSkuVo> skuVoList =new ArrayList<>();
            for (int i = 0; i < rows.size(); i++) {
                List<SearchHit> hitList = Arrays.asList((SearchHit[])skuMap.get(rows.get(i)));
                List<Map> list=new ArrayList<>();
                for (int j = 0; j < hitList.size(); j++) {
                    Map sourceAsMap = hitList.get(j).getSourceAsMap();
                    list.add(sourceAsMap);
                }
                skuVoList.add(new YzProSkuVo(rows.get(i),list));
            }
            return  new BoostrapDataGrid(boostrapDataGrid.getTotal(), boostrapDataGrid.getTotal() ==0 ? Collections.EMPTY_LIST :skuVoList);
        }
        return boostrapDataGrid;
    }



    @Override
    public BoostrapDataGrid businessSearch(Map<String, String> map) {
        BoostrapDataGrid dataGrid = esMapper.esSelectCommon(EsIndexConstant.BUSINESS_INDEX, matchQuery("businessName", map.get("keyword")),
                Map.class, (Integer.parseInt(map.get("currentPage")) - 1) * Integer.parseInt(map.get("size")),
                Integer.parseInt(map.get("size")), null,null);
        List<Map<String,String>> rows = (List<Map<String, String>>) dataGrid.getRows();
        if (rows.size()!=0){
            Map listShop = esMapper.proListShop(rows, EsIndexConstant.GOOD_INDEX);
            List<BusinessGoods> resultList =new ArrayList<>();
            for (int i = 0; i < rows.size(); i++) {
                Map<String,Map> shop = (Map) listShop.get(rows.get(i));
                resultList.add(new BusinessGoods(rows.get(i).get("businessId"),rows.get(i).get("businessName"),shop.get("hits")));
            }
            return new BoostrapDataGrid(dataGrid.getTotal(), dataGrid.getTotal() ==0 ? Collections.EMPTY_LIST :resultList);
        }
        return dataGrid;
    }

    @Override
    public BoostrapDataGrid indexProList(IndexSearchQo qo) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if (!StringUtils.isEmpty(qo.getPlateIds())) {
/*            queryBuilder.must(QueryBuilders.boolQuery().should(wildcardQuery("plateIds", qo.getPlateIds()+"_*"))
                    .should(wildcardQuery("plateIds", "*_" + qo.getPlateIds() + "_*"))
                    .should(wildcardQuery("plateIds", "*_" + qo.getPlateIds())));*/

            queryBuilder.should(wildcardQuery("plateIds", qo.getPlateIds()+"_*"))
                    .should(wildcardQuery("plateIds", "*_" + qo.getPlateIds() + "_*"))
                    .should(wildcardQuery("plateIds", "*_" + qo.getPlateIds())).minimumShouldMatch(1);

        }else {
            queryBuilder.must(termQuery("isRecommend","1"));
        }
        String type;
        if (qo.getId()!=0){
            if (qo.getLevel()==1){
                type="oneType";
            }else if (qo.getLevel()==2){
                type="twoType";
            }else if (qo.getLevel()==3){
                type="threeType";
            }else {
                type="fourType";
            }
            queryBuilder.must(termQuery(type,String.valueOf(qo.getId())));
        }
        return esMapper.esSelectCommon(EsIndexConstant.GOOD_INDEX,queryBuilder,Map.class,qo.getStarIndex(),qo.getPageSize(),"index",null);
    }

    @Override
    public R yzBusinessTypeSearch(ShopTypeGoodQo qo) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.should(termQuery("bussTypeId", qo.getBussTypeId()))
                .should(wildcardQuery("bussTypeId", qo.getBussTypeId() + ",*"))
                .should(wildcardQuery("bussTypeId", "*," + qo.getBussTypeId())).minimumShouldMatch(1);
        BoostrapDataGrid boostrapDataGrid = esMapper.esSelectCommon(EsIndexConstant.COMMUNITY_GOOD_INDEX, queryBuilder, Map.class, qo.getStarIndex(), qo.getPageSize(), "index", 2);
        if (boostrapDataGrid.getTotal()>0){
            List<?> goodList = boostrapDataGrid.getRows();
            HashSet<String> goodIdSet=new HashSet<>(goodList.size());
            Map goodMap;
            for (int i = 0; i < goodList.size(); i++) {
                goodMap = (Map) goodList.get(i);
                goodIdSet.add(String.valueOf(goodMap.get("productId")));
            }
            queryBuilder=QueryBuilders.boolQuery();
            queryBuilder.must(termsQuery("productId",goodIdSet));
            List list = esMapper.esSelectList(EsIndexConstant.COMMUNITY_SKU_INDEX, queryBuilder, Map.class, null);
            String productId;
            String skuProId;
            Map skuMap;
            YzProSkuVo yzProSkuVo;
            List<YzProSkuVo> yzProList=new ArrayList<>();
            for (int i = 0; i < goodList.size(); i++) {
                goodMap = (Map) goodList.get(i);
                goodMap.put("count",0);
                yzProSkuVo= new YzProSkuVo();
                yzProSkuVo.setMap(goodMap);
                productId=String.valueOf(goodMap.get("productId"));
                for (int j = 0; j < list.size(); j++) {
                    skuMap = (Map) list.get(j);
                    skuMap.put("count",0);
                    skuProId = String.valueOf(skuMap.get("productId"));
                    if (skuProId.equals(productId)){
                        yzProSkuVo.getSkuList().add(skuMap);
                    }
                }
                yzProList.add(yzProSkuVo);
            }
            return R.ok(new BoostrapDataGrid(boostrapDataGrid.getTotal(),yzProList));
        }else {
            return R.ok(boostrapDataGrid);
        }

    }

    // businessId 商家id  String bussTypeId商家分类id
    @Override
    public BoostrapDataGrid businessType(ShopTypeGoodQo qo) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must(termQuery("businessId",qo.getBusinessId()));
        queryBuilder.must(termQuery("bussTypeId",qo.getBussTypeId()));
        return esMapper.esSelectCommon(EsIndexConstant.GOOD_INDEX,queryBuilder,Map.class,qo.getStarIndex(),qo.getPageSize(),null,null);
    }

    @Override
    public Map hotGood() {
        return esMapper.hotGood();
    }

    @Override
    public BoostrapDataGrid sortSearch(Map<String, String> map) {
        String level = map.get("level");
        String id = map.get("id");
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        String type="";
        if ("1".equals(level)){
           type="oneType";
        }else if ("2".equals(level)){
            type="twoType";
        }else if ("3".equals(level)){
            type="threeType";
        }else if ("4".equals(level)){
            type="fourType";
        }
        queryBuilder.must(termQuery(type,id));
        return esMapper.esSelectCommon(EsIndexConstant.GOOD_INDEX,queryBuilder,Map.class,
                (Integer.parseInt(map.get("currentPage"))-1)*Integer.parseInt(map.get("size")),
                Integer.parseInt(map.get("size")),map.get("sort"),null);
    }

    @Override
    public Map yzProductSku(String skuIndex,String proIndex,String id, String productId) {
        return esMapper.yzProductSku(skuIndex,proIndex,id,productId);
    }

    @Override
    public List<Map> purchasedSku(List<Map> list) {
        List<Map> resultList=new ArrayList<>(list.size());
        for (Map map : list) {
            resultList.add(yzProductSku(EsIndexConstant.COMMUNITY_SKU_INDEX,EsIndexConstant.COMMUNITY_GOOD_INDEX,String.valueOf(map.get("skuId")),String.valueOf(map.get("productId"))));
        }
        return resultList;
    }



}
